<?php

namespace App\BO\OrderStatus\FlowTrait;

use App\BO\OrderStatus\OrderStateContext;
use App\BO\OrderStatus\OrderStateDefinition;
use App\BO\OrderStatus\State\Refund\RefundWaitingAdminCheckState;
use App\Entities\OrderEntity;
use App\Entities\OrderRefundEntity;
use App\Entities\OrderRefundModel;
use App\Utils\RefundNoGeneratorUtil;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

trait AdminApplyRefundTrait
{
    /**
     * OA 管理员发起退款操作
     */
    public function adminApplyRefund()
    {
        Log::debug('管理员发起退款');

        $request = request();
        $note = $request->input('reason', '');
        $adminNote = $request->input('remark', '取消订单/退款备注');
        $order = $this->stateContext->getOrder();
        $this->applyRefundOperation($order, $note, $adminNote, OrderRefundModel::TYPE_ADMIN_APPLY);
    }

    /**
     * @param OrderEntity $order
     * @param string $note 用户提交的信息
     * @param string $adminNote 管理员提交的信息
     * @param int $type
     */
    private function applyRefundOperation(OrderEntity $order, $note = '', $adminNote = '', $type = OrderRefundModel::TYPE_USER_APPLY)
    {
        DB::beginTransaction();
        // 1. 增加退款申请记录
        $orderRefund = OrderRefundEntity::getNewInstance();
        $orderRefund->setOrderId($order->getId());
        $orderRefund->setPaymentNo($order->getPaymentNo());
        $orderRefund->setPaymentMethod($order->getPaymentMethod());
        $orderRefund->setRefundNo(RefundNoGeneratorUtil::get());
        $orderRefund->setTotalAmount($order->getTotalAmount());
        $orderRefund->setRefundStatus(OrderStateDefinition::STATE_REFUND_WAITING_CHECK);
        $orderRefund->setPreOrderState($order->getOrderState());
        $orderRefund->setType($type);
        $orderRefund->setNote($note);
        $orderRefund->setAdminNote($adminNote);
        $orderRefund->save();
        Log::debug('添加申请退款记录');

        // 修改 order 数据库
        $this->orderStateModifyStore->toRefundWaitingCheck();
        DB::commit();

        // 将状态设置为退款待审核
        $this->stateContext->setOrderState(OrderStateContext::getInstance(RefundWaitingAdminCheckState::class));
    }
}
